package org.anddev.andengine.extension.svg;
/**
 * @author Eric Depta
 * @since 01:14:00 - 28.02.2011
 */
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import org.anddev.andengine.entity.IEntity;
import org.anddev.andengine.entity.shape.Shape;
import org.anddev.andengine.extension.physics.box2d.PhysicsConnector;
import org.anddev.andengine.extension.physics.box2d.PhysicsWorld;
import org.anddev.andengine.extension.svg.util.constants.SVGConstants;
import org.anddev.andengine.extension.svg.util.texture.TextureHolder;
import org.anddev.andengine.opengl.texture.TextureManager;

import android.content.Context;

import com.badlogic.gdx.physics.box2d.Body;


public class SVGDoc implements SVGConstants{
	private final TreeMap<String,Shape> mShapes = new TreeMap<String,Shape>();
	private final HashMap<String,Body> mBodies = new HashMap<String,Body>();
	private final HashMap<String,TextureHolder> mTextures = new HashMap<String,TextureHolder>();
	
	public final PhysicsWorld mPhysicsWorld;
	public final Context mContext;
	public final TextureManager mTextureManager;
	
	public SVGDoc(final Context pContext, final PhysicsWorld pPhysicsWorld, final TextureManager pTextureManager){
		this.mPhysicsWorld = pPhysicsWorld;
		this.mTextureManager = pTextureManager;
		this.mContext = pContext;
	}
	
	//-- Texture
	
	public TextureHolder createTexture(final String pSource, final int pTextureOptionIndex){
		TextureHolder texHolder;
		if(this.mTextures.containsKey(pSource)){
			texHolder = this.mTextures.get(pSource);
		}else{
			texHolder = new TextureHolder(this.mContext, pSource);
			this.mTextures.put(pSource, texHolder);
		}
		texHolder.addTexture(pTextureOptionIndex, this.mTextureManager);
		return texHolder;
	}
	
	//-- Shapes
	
	public Shape addShape(final String pName,final Shape pShape){
		return this.mShapes.put(pName, pShape);
	}
	
	public Shape getShape(final String pName){
		if(this.mShapes.containsKey(pName)){
			return this.mShapes.get(pName);
		}else{
			return null;
		}
	}
	
	public TreeMap<String,Shape> getShapes(){
		return this.mShapes;
	}
	
	public void addShapesEntities(IEntity pEntity){
	    for ( Map.Entry<String, Shape> e : mShapes.entrySet() ){
	    	pEntity.attachChild(e.getValue());
		}
	}
	
	//-- Bodies
	
	public void addBody(final String pName,final Body pBody){
		this.mBodies.put(pName, pBody);
	}
	
	public Body getBody(final String pName){
		if(this.mBodies.containsKey(pName)){
			return this.mBodies.get(pName);
		}else{
			return null;
		}
	}
	
	public HashMap<String,Body> getBodies(){
		return this.mBodies;
	}
	
	//-- remove all
	//TODO remove from treemap, romve textures
	
	public void removeAllBodyAndShapes(IEntity pEntity){
		this.removeAllShapes(pEntity);
		this.removeAllBody(pEntity);
		this.mBodies.clear();
		this.mShapes.clear();
	}
	
	public void removeAllBody(IEntity pEntity){
		for ( Map.Entry<String, Body> e : this.mBodies.entrySet() ){
	    	this.removeBody(pEntity, e.getValue());
		}
	}
	
	public void removeAllShapes(IEntity pEntity){
		for ( Map.Entry<String, Shape> e : this.mShapes.entrySet() ){
			this.removeShape(pEntity, e.getValue());
		}
	}
	
	public void removeBody(IEntity pEntity, String pName){
		this.removeBody(pEntity, this.getBody(pName));
	}
	
	public void removeBody(IEntity pEntity, Body pBody){
    	for(int i = this.mPhysicsWorld.getPhysicsConnectorManager().size() - 1; i >= 0; i--){
    		final PhysicsConnector physicConnector = this.mPhysicsWorld.getPhysicsConnectorManager().get(i);
    		if(physicConnector.getBody() == pBody){
    			this.mPhysicsWorld.unregisterPhysicsConnector(physicConnector);
    		}
    	}
    	this.mPhysicsWorld.destroyBody(pBody);
	}
	
	public void removeShape(IEntity pEntity, String pName){
		this.removeShape(pEntity, this.getShape(pName));
	}
	
	public void removeShape(IEntity pEntity, Shape pShape){
		pShape.detachChildren();
		pShape.clearTouchAreas();
	    pEntity.unregisterTouchArea(pShape);
	    pEntity.detachChild(pShape);
	}
}
